module.exports = function(lab) {
    return {
        @getDepartmentsForStore: function(currentOU, store_id) {
            return lab.query("slime_departments", {
                "conditions": ["store_id = ?", "removed = ?", "ouid = ?"],
                "params": [store_id, false, currentOU.id]
            }).then(function({ list }) {
                this.next(list)
            })
        },
        getAssociatesForStore: function(session, store_id) {
            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }
            let result = {}
            return lab.slime.store.@getDepartmentsForStore(session.currentOU, store_id).then(function(departments) {
                return @.async.all(departments, function(department) {
                    return lab.slime_directory.core.@getDefaultIdentity(session.currentOU, department.id).then(function(identity) {
                        return lab.slime_directory.core.@getAssociatesWithIdentity(session.currentOU, identity.id).then(function(associates) {
                            result[department.id] = {
                                department,
                                default_identity: identity,
                                default_associates: associates
                            }
                            return lab.query(["slime_associates as associate left outer join slime_department_identities as identity ",
                                "on associate.identity_id = identity.id and identity.department_id = ? left outer join slime_store_identities as store_identity ",
                                "on identity.name = store_identity.name"
                            ].join(""), {
                                "fields": ["associate.*", "identity.name as identity", "identity.access"],
                                "conditions": ["associate.removed = ?", "identity.removed = ?", "store_identity.removed = ?"],
                                "params": [department.id, false, false, false],
                                "mapper": (record) => {
                                    record.access = JSON.parse(record.access)
                                    return record
                                }
                            }).then(function({ list }) {
                                result[department.id].associates = list
                                this.next()
                            })
                        })
                    })
                })
            }).resolve(result)
        },
        "searchIdentities": function(session, { start, limit, name }) {
            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }
            let conditions = ["removed = ?"]
            let params = [false]
            if (name) {
                conditions.push("name like ?")
                params.push(`%${name}%`)
            }
            return lab.query("slime_store_identities", {
                conditions,
                params,
                start,
                limit,
                mapper: (record) => {
                    record.access = JSON.parse(record.access)
                    return record
                }
            })
        },
        "changeIdentity": function(session, { associate_id, store_identity_id }) {
            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }
            return lab.slime_directory.core.@getAssociate(session.currentOU, associate_id).then(function(associate) {
                return lab.slime_directory.core.@getDepartmentByID(session.currentOU, associate.department_id).then(function(department) {
                    return lab.find("slime_store_identities", store_identity_id).then(function(store_identity) {
                        return lab.slime_directory.core.@updateIdentityForStore(store_identity, department).then(function(identity) {
                            associate.identity_id = identity.id
                            return lab.slime_directory.core.@updateAssociate(session.currentOU, associate)
                        })
                    })
                })
            })
        },
        "createIdentity": function(session, { name, access }) {
            return lab.create("slime_store_identities", {
                id: @.uuid(),
                name,
                access,
                removed: false,
                create_date: Date.now(),
                update_date: Date.now()
            }).then(function(result) {
                @mew.auto("slime.store.identity", {
                    info: result,
                    action: "create"
                })
                this.next(result)
            })
        },
        "updateIdentity": function(session, { id, name, access }) {
            return lab.find("slime_store_identities", id).then(function(result) {
                if (result) {
                    result.name = name
                    result.access = access
                    result.update_date = Date.now()
                    return lab.update("slime_store_identities", result)
                } else {
                    throw @lab.errors.object_not_found
                }
            }).then(function(result) {
                @mew.auto("slime.store.identity", {
                    info: result,
                    action: "update"
                })
                this.next(result)
            })
        },
        "deleteIdentity": function(session, id) {
            return lab.find("slime_store_identities", id).then(function(result) {
                if (result) {
                    result.removed = true
                    return lab.update("slime_store_identities", result)
                } else {
                    throw @lab.errors.object_not_found
                }
            })
        }
    }
}